package com.guojian.jdbc.mapper;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Map;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;

import com.google.common.collect.Maps;
import com.guojian.common.utils.StringUtilsx;

public class MapRowMapper<T> implements RowMapper<Map<String, T>> {

	private Class<T> mapperClass;

	private boolean isAddLowerCaseOfName = false;

	public MapRowMapper(Class<T> mapperClass, boolean isAddLowerCaseOfName) {
		this.mapperClass = mapperClass;
		this.isAddLowerCaseOfName = isAddLowerCaseOfName;
	}

	public MapRowMapper(boolean isAddLowerCaseOfName) {
		this.isAddLowerCaseOfName = isAddLowerCaseOfName;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, T> mapRow(ResultSet rs, int rowNum) throws SQLException {
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();
		Map<String, T> mapOfColValues = createColumnMap(columnCount);
		for (int i = 1; i <= columnCount; i++) {
			String columnName = JdbcUtils.lookupColumnName(rsmd, i);
			T columnValue = (T) getColumnValue(rs, i);
			mapOfColValues.put(columnName, columnValue);
			if (isAddLowerCaseOfName) {
				mapOfColValues.putIfAbsent(StringUtilsx.toLowerCaseOfCamel(columnName), columnValue);
			}
		}
		return mapOfColValues;
	}

	protected Map<String, T> createColumnMap(int columnCount) {
		if (isAddLowerCaseOfName) {
			return Maps.newLinkedHashMap();
		}
		return new LinkedCaseInsensitiveMap<T>(columnCount);//不区分大小写,小写会把大写的变量名覆盖
	}

	protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
		if (this.mapperClass != null && this.mapperClass != Object.class) {
			return getColumnValue(rs, index, this.mapperClass);
		}
		return JdbcUtils.getResultSetValue(rs, index);
	}

	protected Object getColumnValue(ResultSet rs, int index, Class<T> mapperClass) throws SQLException {
		return JdbcUtils.getResultSetValue(rs, index, mapperClass);
	}

	public static void main(String[] args) {

	}

}
